package com.derbysoft.lowcostadapter.dswitch3.service.impl;

import com.derbysoft.dswitch.dto.common.KeyValue;
import com.derbysoft.dswitch.remote.hotel.dto.ErrorDTO;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailRequest;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailResponse;
import com.derbysoft.lowcostadapter.commons.dto.Search;
import com.derbysoft.lowcostadapter.commons.dto.SearchResponse;
import com.derbysoft.lowcostadapter.commons.exception.NetErrorException;
import com.derbysoft.lowcostadapter.commons.utils.ErrorMessageUtils;
import com.derbysoft.lowcostadapter.dswitch3.handler.impl.ElapsedTimeType;
import com.derbysoft.lowcostadapter.dswitch3.service.DS3FlushCacheService;
import com.derbysoft.lowcostadapter.dswitch3.service.HotelProviderService;
import com.derbysoft.lowcostadapter.dswitch3.translate.Translator;
import com.derbysoft.lowcostadapter.webservice.LowCostWebService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

/**
 * Created by: jason
 * Date: 2012-5-8
 */
@Service("ds3GetAvailService")
public class HotelAvailServiceImpl extends BaseHotelService
        implements HotelProviderService<HotelAvailRequest, HotelAvailResponse> {

    private static Logger logger = LoggerFactory.getLogger(HotelAvailServiceImpl.class);

    @Autowired
    @Qualifier("ds3HotelAvailRQTranslator")
    private Translator<HotelAvailRequest, Search, Void> hotelAvailRQTranslator;

    @Autowired
    @Qualifier("ds3HotelAvailRSTranslator")
    private Translator<SearchResponse, HotelAvailResponse, HotelAvailRequest> hotelAvailRSTranslator;

    @Autowired
    @Qualifier("searchWebService")
    private LowCostWebService getAvailWebService;

    @Autowired
    private DS3FlushCacheService ds3FlushCacheService;

    @Override
    public HotelAvailResponse execute(HotelAvailRequest request) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        try {

            Search search = hotelAvailRQTranslator.translate(request, null);

            SearchResponse searchResponse = (SearchResponse) getAvailWebService.send(search);

            stopWatch.stop();
            long elapsedTime = stopWatch.getTotalTimeMillis();

            HotelAvailResponse response = hotelAvailRSTranslator.translate(searchResponse, request);

            ds3FlushCacheService.flushCache(request, response);

            response.getElapsedTimes().add(new KeyValue(ElapsedTimeType.LCB_AVAIL.name(), String.valueOf(elapsedTime)));

            return response;

        } catch (Exception ex) {
            if (stopWatch.isRunning()) {
                stopWatch.stop();
            }
            String webserviceTime = String.valueOf(stopWatch.getTotalTimeMillis());
            HotelAvailResponse failedResponse = createErrorResponse(request, ex);
            failedResponse.getElapsedTimes().add(new KeyValue(ElapsedTimeType.LCB_AVAIL.name(), webserviceTime));
            return failedResponse;
        }
    }

    private HotelAvailResponse createErrorResponse(HotelAvailRequest request, Exception ex) {
        HotelAvailResponse response = new HotelAvailResponse();
        response.setTaskId(request.getHeader().getTaskId());
        ErrorDTO errorDTO = new ErrorDTO();
        errorDTO.setCode(SYSTEM);
        errorDTO.setSource(ex instanceof NetErrorException ? provider : adapter);
        errorDTO.setMessage(ErrorMessageUtils.buildErrorMessage(ex));
        response.setError(errorDTO);
        return response;
    }
}
